24 #define foreach(x, v) for (typeof (v).begin() x=(v).begin(); x !=(v).end(); ++x)
25 #define For(i, a, b) for (int i=(a); i<(b); ++i)
26 #define D(x) cout << #x " is " << x << endl
28 const double EPS
= 1e-9;
29 int cmp(double x
, double y
= 0, double tol
= EPS
) {
30 return (x
<= y
+ tol
) ? (x
+ tol
< y
) ? -1 : 0 : 1;
34 const int MAXH
= 1501;
36 /////////////// Maximum flow for sparse graphs ///////////////
37 /////////////// Complexity: O(V * E^2) ///////////////
41 initialize_max_flow();
42 Create graph using add_edge(u, v, c);
43 max_flow(source, sink);
45 WARNING: The algorithm writes on the cap array. The capacity
46 is not the same after having run the algorithm. If you need
47 to run the algorithm several times on the same graph, backup
52 const int MAXN
= MAXH
* 4 + 2;
53 const int MAXE
= (MAXH
* (MAXH
+ 1) + 4 * MAXH
); //Maximum number of edges
54 const int oo
= INT_MAX
/ 4;
59 unsigned short cap
[MAXE
];
63 Builds a directed edge (u, v) with capacity c.
64 Note that actually two edges are added, the edge
65 and its complementary edge for the backflow.
67 int add_edge(int u
, int v
, int c
){
68 adj
[current_edge
] = v
;
69 cap
[current_edge
] = c
;
70 next
[current_edge
] = first
[u
];
71 first
[u
] = current_edge
++;
73 adj
[current_edge
] = u
;
74 cap
[current_edge
] = 0;
75 next
[current_edge
] = first
[v
];
76 first
[v
] = current_edge
++;
79 void initialize_max_flow(){
81 memset(next
, -1, sizeof next
);
82 memset(first
, -1, sizeof first
);
87 //arrived_by[i] = The last edge used to reach node i
88 int find_augmenting_path(int src
, int snk
){
90 Make a BFS to find an augmenting path from the source to
91 the sink. Then pump flow through this path, and return
92 the amount that was pumped.
94 memset(arrived_by
, -1, sizeof arrived_by
);
98 while (h
< t
&& arrived_by
[snk
] == -1){ //BFS
100 for (int e
= first
[u
]; e
!= -1; e
= next
[e
]){
102 if (arrived_by
[v
] == -1 && cap
[e
] > 0){
109 if (arrived_by
[snk
] == -1) return 0;
114 if (cap
[arrived_by
[cur
]] < neck
) neck
= cap
[arrived_by
[cur
]];
115 cur
= adj
[arrived_by
[cur
] ^ 1];
120 //Remove capacity from the edge used to reach node "cur"
121 //Add capacity to the backedge
122 cap
[arrived_by
[cur
]] -= neck
;
123 cap
[arrived_by
[cur
] ^ 1] += neck
;
124 //move backwards in the path
125 cur
= adj
[arrived_by
[cur
] ^ 1];
130 int max_flow(int src
, int snk
){
132 while ((neck
= find_augmenting_path(src
, snk
)) != 0){
139 const int src
= MAXH
* 4, sink
= src
+ 1;
141 int face(int number
, bool isBoy
) {
142 int ans
= isBoy
? 0 : 2 * MAXH
;
143 if (number
< 0) ans
+= -number
;
144 else ans
+= number
+ MAXH
;
146 //printf("number = %d, isBoy = %d, ans = %d\n", number, isBoy, ans);
147 assert(ans
< 4 * MAXH
);
151 unsigned short cnt
[4 * MAXH
];
157 for (int i
= 0; i
< n
; ++i
) {
158 int x
; scanf("%d", &x
);
159 assert(1500 <= abs(x
) and abs(x
) <= 2500);
160 int k
= face(x
, true);
162 //printf("cnt[boy = %d] = %d\n", x, cnt[k]);
164 for (int i
= 0; i
< n
; ++i
) {
165 int x
; scanf("%d", &x
);
166 assert(1500 <= abs(x
) and abs(x
) <= 2500);
167 int k
= face(x
, false);
169 //printf("cnt[girl = %d] = %d\n", x, cnt[k]);
172 //Flow::init(Flow::maxnode, src, sink);
173 Flow::initialize_max_flow();
175 for (int boy
= -2500; boy
<= -1500; ++boy
) {
176 if (cnt
[face(boy
, true)] == 0) continue;
177 for (int girl
= 1500; girl
< -boy
; ++girl
) {
178 if (cnt
[face(girl
, false)] == 0) continue;
179 Flow::add_edge(face(boy
, true), face(girl
, false), Flow::oo
);
180 //printf("Added edge from boy = %d to girl = %d\n", boy, girl);
184 for (int boy
= 1500; boy
<= 2500; ++boy
) {
185 if (cnt
[face(boy
, true)] == 0) continue;
186 for (int girl
= -boy
-1; girl
>= -2500; --girl
) {
187 if (cnt
[face(girl
, false)] == 0) continue;
188 Flow::add_edge(face(boy
, true), face(girl
, false), Flow::oo
);
189 //printf("Added edge from boy = %d to girl = %d\n", boy, girl);
193 for (int k
= 1500; k
<= 2500; ++k
) {
194 if (cnt
[face(k
, true)] > 0) {
195 Flow::add_edge(src
, face(k
, true), cnt
[face(k
, true)]);
197 if (cnt
[face(-k
, true)] > 0) {
198 Flow::add_edge(src
, face(-k
, true), cnt
[face(-k
, true)]);
201 if (cnt
[face(k
, false)] > 0) {
202 Flow::add_edge(face(k
, false), sink
, cnt
[face(k
, false)]);
205 if (cnt
[face(-k
, false)] > 0) {
206 Flow::add_edge(face(-k
, false), sink
, cnt
[face(-k
, false)]);
210 //int ans = Flow::dinic_flow();
211 int ans
= Flow::max_flow(src
, sink
);